package Imp.Service.ImpServiceImp;

import Imp.Service.ImpService;
import Imp.clients.openFeignFourth;
import Imp.clients.openFeignThird;
import Imp.mappers.usemapper;
import entity.Item;
import entity.Order;
import entity.Result;
import feign.FeignException;
import lombok.extern.slf4j.Slf4j;
import org.apache.seata.spring.annotation.GlobalTransactional;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.concurrent.ListenableFutureCallback;

import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Service
public class ImpServiceImp implements ImpService {

    @Autowired
    usemapper usemapper;

    @Autowired
    openFeignThird openFeignThird;
    @Autowired
    openFeignFourth openFeignFourth;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @GlobalTransactional
    @Override
    public int ToAddOrder(Integer userid, Integer itemid, Integer num) {

        try {
            Item item = openFeignThird.getItem(itemid);
            if (item == null) {
                log.info("不存在该商品");
            }
            Integer price = item.getPrice();
            LocalDateTime order_now = LocalDateTime.now();
            //todo 下订单
            usemapper.addOrder(itemid, userid, price, num, order_now, 0);
            int orderId = usemapper.getLastInsertId();
            log.info("获取的订单id:{}",orderId);
            //todo 扣减库存
            Map<String, Object> map = new HashMap<>();
            map.put("itemid", itemid);
            map.put("num", num);
            CorrelationData cd = new CorrelationData(UUID.randomUUID().toString());
            cd.getFuture().addCallback(new ListenableFutureCallback<CorrelationData.Confirm>() {
                @Override
                public void onSuccess(CorrelationData.Confirm result) {
                    if (result.isAck()) {
                        log.info("收到消息ack");
                    } else {
                        log.error("收到消息nack,失败原因：{}", result.getReason());
                    }
                }

                @Override
                public void onFailure(Throwable ex) {
                    log.error("amqp 处理出现错误:");
                }
            });
            rabbitTemplate.convertAndSend("amp.gy.direct", "success", map, cd);
            //TODO  发送延时消息
            rabbitTemplate.convertAndSend("delay.direct","delay",orderId, message -> {
                message.getMessageProperties().setDelay(10000);
                return message;
            });
            return orderId;
        } catch (FeignException e) {
            log.error("报错信息为：{}", e.toString());
        }

        return 0;
    }

    @Override
    public Result PayService(int orderId) {
        log.info("扣减用户余额");
        LocalDateTime now = LocalDateTime.now();
        Order order = usemapper.getOrder(orderId);
        if (order == null) {
            log.info("订单为空？");
            return new Result("订单异常", 400, "订单缺失");
        }
        int userid = order.getUserid();
        float price = (float) order.getPrice();
        int number = order.getNumber();
        try {
            usemapper.subtractUserMoney(number * price, userid, now);
        } catch (Exception e) {
            SQLException sqlException = (SQLException) e.getCause();
            if (sqlException.getSQLState().equals("HY000")) {
                return new Result("扣减余额失败", 400, "余额不足");
            }
        }
        usemapper.setOrderToPay(orderId);
        return new Result("用户已扣减余额", 200, null);

    }
}